home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1997 April
/
EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso
/
EARCD
/
comm
/
bbs
/
Hydra11s.lha
/
HBBS
/
Source
/
Oberon
/
MenuPrompt.mod
< prev
next >
Wrap
Text File
|
1996-07-05
|
8KB
|
347 lines
MODULE MenuPrompt;
IMPORT
a:= Arguments, ac:= ANSIConsole, st:= Strings, cv:= Conversions, io, s:= SYSTEM,
e:= Exec, d:= Dos, ol:= OberonLib,
bo:= BBSColours, bs:= BBSStructures, bc:= BBSConstants,
hn:= HBBSNode, hc:= HBBSCommon, req:= Requests;
CONST EOF = -1; LF = 0AH;
LineLength = 80;
LTRUE = 1; LFALSE = 0;
TYPE
LineNodePtr = UNTRACED POINTER TO LineNode;
LineNode = STRUCT
prev, next: LineNodePtr;
text: ARRAY LineLength OF CHAR;
END;
VAR
BBSGlobal: bs.BBSGlobalDataPtr;
NnD: bs.NodeDataPtr;
NodeNum: LONGINT;
sLine: ARRAY 80 OF CHAR;
sQuitCmd: ARRAY 80 OF CHAR;
useQuitCmd: BOOLEAN;
argList: LineNodePtr;
CountArgs: INTEGER;
file: d.FileHandlePtr;
textPool: e.MemPoolPtr;
menuName: LineNodePtr;
PROCEDURE cleanup(num: LONGINT);
BEGIN
IF hn.HBBSNodeBase # NIL THEN
hn.HBBSCleanUpDoor;
e.CloseLibrary(hn.HBBSNodeBase);
hn.HBBSNodeBase:= NIL;
END;
IF hc.HBBSCommonBase # NIL THEN
hc.HBBSCleanUpCommon;
e.CloseLibrary(hc.HBBSCommonBase);
hc.HBBSCommonBase:= NIL;
END;
IF num # 0 THEN
io.WriteString("Door Error = ");
io.WriteInt(num, 0); io.WriteLn;
(* io.Format("Door Error = %d\n", s.ADR(num)) *)
END;
END cleanup;
PROCEDURE init(name: e.STRPTR);
BEGIN
IF hc.HBBSCommonBase = NIL THEN
cleanup(1); RETURN
END;
IF NOT hc.HBBSInitCommon() THEN
cleanup(2); RETURN
END;
IF hn.HBBSNodeBase = NIL THEN
cleanup(3); RETURN
END;
IF NOT hn.HBBSInitDoor(SHORT(NodeNum), name) THEN
cleanup(4); RETURN
END;
END init;
PROCEDURE AddNode(VAR list: LineNodePtr; at: INTEGER): LineNodePtr;
VAR last, new: LineNodePtr;
dummy: LineNode;
BEGIN
new:= e.AllocPooled(textPool, s.SIZE(dummy));
IF list = NIL THEN
IF new # NIL THEN
new^.prev:= NIL;
new^.next:= NIL;
END;
list:= new;
ELSE
IF at <= 1 THEN
IF new # NIL THEN
new^.prev:= NIL;
new^.next:= list;
list^.prev:= new;
list:= new;
END;
ELSE
last:= list;
WHILE (last^.next # NIL) & (at > 2) DO
last:= last^.next; at:= at - 1
END;
IF new # NIL THEN
new^.next:= last^.next;
new^.prev:= last;
IF last^.next # NIL THEN
last^.next^.prev:= new
END;
last^.next:= new;
END;
END;
END;
RETURN new;
END AddNode;
PROCEDURE DeleteNode(VAR list: LineNodePtr; at: INTEGER);
VAR this: LineNodePtr;
dummy: LineNode;
BEGIN
IF list # NIL THEN
this:= list;
IF at <= 1 THEN
list:= this^.next;
IF list # NIL THEN list^.prev:= NIL END;
ELSE
WHILE (this^.next # NIL) & (at > 1) DO
this:= this^.next; at:= at - 1
END;
IF this^.prev # NIL THEN
this^.prev^.next:= this^.next
END;
IF this^.next # NIL THEN
this^.next^.prev:= this^.prev;
END;
END;
e.FreePooled(textPool, this, s.SIZE(dummy));
END;
END DeleteNode;
PROCEDURE GetNode(list: LineNodePtr; at: INTEGER): LineNodePtr;
BEGIN
IF list = NIL THEN RETURN NIL END;
WHILE (list # NIL) & (at > 1) DO
list:= list^.next; at:= at - 1;
END;
RETURN list;
END GetNode;
PROCEDURE ReqNumber(l: LONGINT);
VAR str: ARRAY 80 OF CHAR;
ok: BOOLEAN;
count: INTEGER; factor: LONGINT;
BEGIN
factor:= 1000000000; count:= 10;
WHILE (ABS(l) < factor) & (count > 1) DO count:= count - 1; factor:= factor DIV 10 END;
ok:= cv.IntToString(l, str, count);
IF ok THEN
req.BreakPoint(str)
END;
END ReqNumber;
VAR str: ARRAY 80 OF CHAR;
PROCEDURE PutNumber(l: LONGINT);
VAR ok: BOOLEAN;
count: INTEGER; factor: LONGINT;
BEGIN
factor:= 1000000000; count:= 10;
WHILE (ABS(l) < factor) & (count > 1) DO count:= count - 1; factor:= factor DIV 10 END;
ok:= cv.IntToString(l, str, count);
IF ok THEN
hn.DOORWriteText(s.ADR(str));
END;
END PutNumber;
VAR str1: ARRAY 2 OF CHAR;
PROCEDURE PutChar(ch: CHAR);
BEGIN
str1[0]:= ch; str1[1]:= CHR(0);
hn.DOORWriteText(s.ADR(str1));
END PutChar;
PROCEDURE ReplyArgs;
VAR
i: INTEGER;
thisArg: LineNodePtr;
BEGIN
i:= 1;
LOOP
thisArg:= GetNode(argList, i);
IF thisArg # NIL THEN hn.DOORWriteText(s.ADR(thisArg^.text)) END;
hn.DOORWriteText(s.ADR(" "));
IF thisArg = NIL THEN EXIT END;
i:= i + 1
END;
END ReplyArgs;
PROCEDURE DoorMain;
CONST MaxCharsTag ="MAXCHARS="; QuitCommandTag = "QUITCMD=";
VAR
NoDisplayMenu, NoPausePrompt, menuDisplayed: BOOLEAN;
error, result, maxChars, pos, len, flags: LONGINT;
prompt, command, doorname, option: ARRAY 80 OF CHAR;
BEGIN
(* ReplyArgs; *)
NoDisplayMenu:= st.Occurs(NnD^.ActiveDoor^.SystemOptions^, "NOMENU") >= 0;
NoPausePrompt:= st.Occurs(NnD^.ActiveDoor^.SystemOptions^, "NOPAUSE") >= 0;
pos:= st.Occurs(NnD^.ActiveDoor^.SystemOptions^, MaxCharsTag);
IF pos >= 0 THEN
st.Cut(NnD^.ActiveDoor^.SystemOptions^, pos + SIZE(MaxCharsTag), 80, option);
len:= st.Occurs(option, " ");
IF len >= 0 THEN
st.Cut(option, 0, len, option);
END;
IF NOT cv.StringToInt(option, maxChars) THEN
maxChars:= 0
END;
ELSE
maxChars:= 0
END;
pos:= st.Occurs(NnD^.ActiveDoor^.SystemOptions^, QuitCommandTag);
useQuitCmd:= pos >= 0;
IF pos >= 0 THEN
st.Cut(NnD^.ActiveDoor^.SystemOptions^, pos + SIZE(QuitCommandTag), 80, sQuitCmd);
len:= st.Occurs(sQuitCmd, " ");
IF len >= 0 THEN
st.Cut(sQuitCmd, 0, len, sQuitCmd);
END;
st.Upper(sQuitCmd);
END;
flags:= bc.GlEdit + bc.GlHistory + bc.GlDisplay;
IF maxChars > 0 THEN flags:= flags + bc.GlImmediate END;
REPEAT
error:= 0;
IF (NnD^.User.CallData.UserType = bc.UserTypeNormal) & (NOT NoDisplayMenu) & (NOT menuDisplayed) THEN
IF NOT NoPausePrompt THEN
IF hn.DOORPausePrompt(NIL) # 0 THEN error:= 1 END;
END;
IF hn.DOORDisplaySpecialScreen(s.ADR("MENU")) # bc.LTRUE THEN END;
END;
menuDisplayed:= FALSE;
IF bc.nFlagOLMWaiting IN NnD^.NodeFlags THEN
IF hn.DOORSystemDoor(s.ADR("ReadOLM"), NIL) # 0 THEN error:= 3 END;
END;
IF NnD^.CurrentConf # NIL THEN
hc.strNcpy(s.ADR(prompt), NnD^.CurrentConf^.MenuPrompt, 79);
hc.strNcpy(s.ADR(prompt), hn.HBBSModifyString(s.ADR(prompt)), 79);
ELSE
prompt:= ">"
END;
hn.DOORWriteText(s.ADR(prompt)); hn.DOORWriteText(s.ADR(" "));
result:= hn.DOORGetLine(flags, CHR(0), maxChars, 0, NIL);
hc.strNcpy(s.ADR(command), NnD^.CurrentLine, 79);
hc.RemoveSpaces(s.ADR(command));
IF st.Length(command) > 0 THEN
pos:= hc.iPosition(s.ADR(" "), s.ADR(command));
IF pos < 0 THEN pos:= st.Length(command) END;
hc.strNcpy(s.ADR(doorname), s.ADR(command), SHORT(pos));
hc.StrFCpy(s.ADR(option), s.ADR(command), SHORT(pos + 1));
IF st.Occurs(doorname, "?") >= 0 THEN
IF hn.DOORDisplaySpecialScreen(s.ADR("MENU")) # bc.LTRUE THEN END;
menuDisplayed:= TRUE;
ELSE
IF hn.DOORUserDoor(s.ADR(doorname), s.ADR(option)) # bc.LTRUE THEN END;
END;
ELSE
ac.UP(PutChar, 1);
menuDisplayed:= TRUE;
END;
IF (hn.CarrierLost()= e.LTRUE) & (NnD^.LoginType = bc.LoginRemote) THEN
NnD^.OnlineStatus:= bc.OSOffline
END;
IF error # 0 THEN
hn.DOORWriteText(s.ADR("Menu error #")); PutNumber(error);
hn.DOORWriteText(s.ADR("\n"));
error:= 0
END;
st.Upper(doorname);
UNTIL (NnD^.OnlineStatus # bc.OSOnline) OR ((st.Occurs(sQuitCmd, doorname) = 0) & useQuitCmd);
END DoorMain;
PROCEDURE ParseArgs;
VAR
i: INTEGER;
newArg: LineNodePtr;
s: ARRAY 80 OF CHAR;
ok: BOOLEAN;
BEGIN
CountArgs:= a.NumArgs();
i:= 1;
WHILE i <= CountArgs DO
newArg:= AddNode(argList, MAX(INTEGER));
IF newArg # NIL THEN
a.GetArg(i, newArg^.text);
ELSE
CountArgs:= i;
END;
i:= i + 1
END;
END ParseArgs;
VAR
newArg: LineNodePtr;
dummy: LineNode;
BEGIN
textPool:= e.CreatePool(LONGSET{}, s.SIZE(dummy), s.SIZE(dummy));
ParseArgs;
IF CountArgs > 0 THEN
newArg:= GetNode(argList, 1);
IF cv.StringToInt(newArg^.text, NodeNum) THEN
init(s.ADR("MenuPrompt"));
IF hc.HBBSCommonBase # NIL THEN
BBSGlobal:= hc.HBBSGimmeBBS();
IF BBSGlobal # NIL THEN
NnD:= hc.HBBSNodeDataPtr(SHORT(NodeNum));
IF NnD # NIL THEN
DoorMain;
END;
END;
END;
cleanup(0);
ELSE
io.WriteString("Invalid Param for door!\n")
END;
ELSE
io.WriteString("No Param for door!\n");
END;
CLOSE
cleanup(0);
e.DeletePool(textPool);
END MenuPrompt.